package com.zhlq.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * 提供静态方法取得Spring上下文中的bean。
 * 实现ApplicationContextAware接口，以便于在Spring启动时注入ApplicationContext对象。
 * 如果项目有多个SpringContext上下文，请在每处配置该bean。
 * @author zhangyu
 *
 */
public class SpringContext implements ApplicationContextAware{
	
	/** Spring全局上下文 */
	private static HashMap<String, ApplicationContext> contexts = new HashMap<String, ApplicationContext>();
	
	/**
	 * 跟据bean的Id，从Spring上下文中取得Bean对象
	 * @param beanId
	 * @return
	 */
	public static Object getBean(String beanId){
		Set<Entry<String,ApplicationContext>> entrySet = contexts.entrySet();
		Iterator<Entry<String, ApplicationContext>> iterator = entrySet.iterator();
		while(iterator.hasNext()){
			Entry<String, ApplicationContext> next = iterator.next();
			ApplicationContext context = next.getValue();
			Object bean = context.getBean(beanId);
			if(bean != null){
				return bean;
			}
		}
		return null;
	}
	
	/**
	 * 跟据对象的Class，从Spring上下文中取得Bean对象
	 * @param cls对象的类
	 * @return
	 */
	public static <T> T getBean(Class<T> cls){
		Set<Entry<String,ApplicationContext>> entrySet = contexts.entrySet();
		Iterator<Entry<String, ApplicationContext>> iterator = entrySet.iterator();
		while(iterator.hasNext()){
			Entry<String, ApplicationContext> next = iterator.next();
			ApplicationContext context = next.getValue();
			try {
				T bean = context.getBean(cls);
				if(bean != null){
					return bean;
				}
			} catch (NoSuchBeanDefinitionException e) {				
			}
		}
		return null;
	}
	
	/**
	 * 跟据bean的Id，从指定Id的Spring上下文中取得Bean对象
	 * @param beanId
	 * @return
	 */
	public static Object getBean(String beanId, String contextId){
		ApplicationContext context = contexts.get(contextId);
		if(context == null){
			return null;
		}else{
			return contexts.get(contextId).getBean(beanId);		
		}
	}
	
	/**
	 * 跟据对象的Class，从指定Id的Spring上下文中取得Bean对象
	 * @param cls对象的类
	 * @return
	 */
	public static <T> T getBean(Class<T> cls, String contextId){
		ApplicationContext context = contexts.get(contextId);
		if(context == null){
			return null;
		}else{
			return context.getBean(cls);			
		}
	}
	
	/**
	 * 取得指定Id的Spring上下文
	 * @param contextId
	 * @return
	 */
	public static ApplicationContext getContext(String contextId){
		return contexts.get(contextId);
	}

	@Override
	public void setApplicationContext(ApplicationContext appContext)
			throws BeansException {	
		contexts.put(appContext.getId(), appContext);
	}
}
